package cn.ljy.common.utils.alibaba;

import cn.ljy.common.exception.model.SmsException;
import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;
import darabonba.core.client.ClientOverrideConfiguration;

import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

public class SmsCodeSender {

    // ========== 配置区（建议放到 application.yml 或配置中心）==========
    private static final String ACCESS_KEY_ID = "LTAI5tR1jMvugkkFGJxPFHkg";
    private static final String ACCESS_KEY_SECRET = "fK2jzsobg7CkBDGjMGknmVwjaC6Meb";
    private static final String ENDPOINT = "dysmsapi.aliyuncs.com";
    private static final String SIGN_NAME = "柳州小农科技";
    private static final String TEMPLATE_CODE = "SMS_327662254";
    private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(10); // 同步等待超时
    // ===========================================================

    private final AsyncClient client;

    public SmsCodeSender() {
        StaticCredentialProvider provider = StaticCredentialProvider.create(
                Credential.builder()
                        .accessKeyId(ACCESS_KEY_ID)
                        .accessKeySecret(ACCESS_KEY_SECRET)
                        .build()
        );
        this.client = AsyncClient.builder()
                .credentialsProvider(provider)
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                .setEndpointOverride(ENDPOINT)
                )
                .build();
    }

    /**
     * 发送手机验证码
     *
     * @param phoneNumbers 手机号，支持单个；如需批量请循环调用
     * @param code         验证码（由业务方生成，建议6位数字）
     * @return SendSmsResponse
     * @throws SmsException 发送失败时抛出，包含 requestId 便于排查
     */
    public SendSmsResponse sendCode(String phoneNumbers, String code) throws SmsException {
        // 1) 参数校验
        validate(phoneNumbers, code);

        // 2) 构造请求
        SendSmsRequest request = SendSmsRequest.builder()
                .phoneNumbers(phoneNumbers)
                .signName(SIGN_NAME)
                .templateCode(TEMPLATE_CODE)
                .templateParam("{\"code\":\"" + code + "\"}")
                .build();

        // 3) 发送并等待结果（带超时）
        try {
            CompletableFuture<SendSmsResponse> future = client.sendSms(request);
            SendSmsResponse resp = future.get(REQUEST_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
            if (!"OK".equalsIgnoreCase(resp.getBody().getCode())) {
                throw new SmsException("SendSms failed, Code=" + resp.getBody().getCode() +
                        ", Message=" + resp.getBody().getMessage() +
                        ", RequestId=" + resp.getBody().getRequestId());
            }
            return resp;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new SmsException("SendSms interrupted, phone=" + phoneNumbers, e);
        } catch (java.util.concurrent.TimeoutException e) {
            throw new SmsException("SendSms timeout, phone=" + phoneNumbers, e);
        } catch (Exception e) {
            throw new SmsException("SendSms error, phone=" + phoneNumbers, e);
        }
    }

    private void validate(String phoneNumbers, String code) throws SmsException {
        if (phoneNumbers == null || phoneNumbers.trim().isEmpty()) {
            throw new SmsException("手机号不能为空");
        }
        // 简单大陆手机号正则（可按需放宽或收紧）
        if (!Pattern.matches("^1[3-9]\\d{9}$", phoneNumbers.trim())) {
            throw new SmsException("手机号格式不合法: " + phoneNumbers);
        }
        if (code == null || !Pattern.matches("\\d{4,6}", code)) {
            throw new SmsException("验证码必须为4-6位数字: " + code);
        }
    }

    /** 关闭客户端，应用关闭时调用一次即可 */
    public void close() {
        if (client != null) {
            client.close();
        }
    }

    // ========== 便捷用法示例 ==========
    public static void main(String[] args) {
        SmsCodeSender sender = new SmsCodeSender();
        try {
            SendSmsResponse resp = sender.sendCode("15677031450", "123456");
            System.out.println("SendSms success, BizId=" + resp.getBody().getBizId() +
                    ", RequestId=" + resp.getBody().getRequestId());
        } catch (SmsException e) {
            System.err.println("SendSms failed: " + e.getMessage());
        } finally {
            sender.close();
        }
    }
}
